#pragma once
#include "interfaces.h"
#include <Windows.h>
#include <time.h>
#include "RendererDX9Main.h"

class RandomEngineApp;
class WindowsFramework : public IOSFramework
{
public:
	WindowsFramework() { 
	if(this_ != NULL)
	{
		assert(0 && "Attempt to create second windows framework!");
	}
	this_ = this;
	m_bDeviceLost = false;
	HMODULE hModule = GetModuleHandleW(NULL);
	WCHAR path[MAX_PATH];
	GetModuleFileNameW(hModule, path, MAX_PATH);
	m_ApplicationDir = path;
	}
	~WindowsFramework() { this_ = NULL; }

	std::wstring m_ApplicationDir;
private:
	IRenderer * m_pRenderer; // working renderer. There can be only one working renderer!
	union{ // if it is going to be ported to linux some day, this will be used
	HWND m_hwnd; // rendering window. There an be only one rendering window!
	};
	union{
	HINSTANCE m_hinstance;
	};
	union{
	LPCWSTR m_application_name;
	};
	static WindowsFramework * this_;
	static LRESULT CALLBACK WndProc(HWND hwnd, UINT umessage, WPARAM wparam, LPARAM lparam);
	LRESULT CALLBACK MessageHandler(HWND hwnd, UINT umsg, WPARAM wparam, LPARAM lparam);
	//variables
	bool m_bDeviceLost;
	U32 m_width, m_height;
	//Callback List
	RandomEngineApp * m_RandomEngineApp;
	rndengine_bool_float_func m_updatefunc;
	rndengine_bool_float_func m_renderfunc;
	rndengine_void_void_func m_createdevfunc;
	rndengine_void_void_func m_destroydevfunc;
	rndengine_void_void_func m_resetdevfunc;
	rndengine_void_void_func m_lostdevfunc;
public:
	//general purpose funcs
	const std::wstring& GetApplicationDir();


	virtual void VInitialize(U32 width, U32 height, TCHAR* title, RE_RENDERER renderer_type);
	virtual void VCreateMainWindow(U32 width, U32 height, TCHAR* title);
	virtual void VDestroyMainWindow();
	virtual IRenderer* VCreateRenderer(RE_RENDERER renderer_type);
	virtual void VRun();
	virtual void VShutDown();

	//callbacks
	virtual void SetRandomEngineObject(RandomEngineApp * app);
	virtual void SetUpdateCallback(rndengine_bool_float_func updateclb);
	virtual void SetRenderCallback(rndengine_bool_float_func renderclb);
	virtual void SetCreateDeviceCallback(rndengine_void_void_func createclb);
	virtual void SetDestroyDeviceCallback(rndengine_void_void_func destroyclb);
	virtual void SetResetDeviceCallback(rndengine_void_void_func resetclb);
	virtual void SetLostDeviceCallback(rndengine_void_void_func lostclb);
};